mitmproxy — SSL/TLS 拦截代理系统

mitmproxy 是一套交互式 SSL/TLS 拦截代理工具集,支持 HTTP/1、HTTP/2、WebSocket 和 HTTP/3。 它的名字 MITM 来自 Man-In-The-Middle——通过成为客户端信任的证书颁发机构(CA), 对加密 TLS 流量进行透明解密、检查和修改。 项目纯 Python 实现,由 R0CKER / Aldo Cortesi 主导开发。

仓库github.com/mitmproxy/mitmproxy
官网mitmproxy.org
许可证MIT
技术栈Python 3.10+, asyncio(单线程异步)
安装pip / pipx / brew / 独立二进制 / Docker

1. 概述

mitmproxy 本质上是一个代理服务器(Proxy Server),位于客户端和服务器之间, 能查看、记录、修改双向的 HTTP(S) 流量。与普通 HTTP 代理不同,mitmproxy 通过动态生成拦截证书 来解密 HTTPS 流量,让开发者能像查看明文 HTTP 一样分析加密通信。

三大前端工具

三者关系:三个工具共享同一个核心代理引擎(mitmproxy.proxy), 只是提供了不同的用户界面。切换工具不影响功能和配置。

核心能力

2. 行为分析(做什么)

以下从行为视角分析 mitmproxy 的功能边界与核心流程。

2.1 用例图 — 角色与功能全景

展示三类主要角色与 mitmproxy 系统的交互边界。

mitmproxy 用例图
图 1:mitmproxy 顶层用例图

2.2 活动图 — HTTPS 拦截完整流程

从客户端 CONNECT 到最终请求转发的完整活动链,展示 mitmproxy 核心的 MITM 过程。

mitmproxy HTTPS 拦截活动图
图 2:mitmproxy 显式 HTTPS 拦截活动图

2.3 序列图 — 透明 HTTPS 拦截时序

展示透明代理模式下最复杂场景的完整交互时序:网络层重定向 + TLS MITM。

mitmproxy 透明 HTTPS 拦截序列图
图 3:透明 HTTPS 代理完整时序图

2.4 状态机图 — TLS 拦截连接生命周期

展示 mitmproxy 处理一条 TLS 连接时的完整状态转换:从客户端连接建立到请求转发。

TLS 连接状态机图
图 4:TLS 拦截连接状态机图

3. 结构分析(由什么组成)

以下从结构视角分析 mitmproxy 的组件架构与核心抽象。

3.1 组件图 — 系统宏观架构

展示 mitmproxy 的前端工具、核心引擎与协议层的分层组件架构。

mitmproxy 组件架构图
图 5:mitmproxy 系统组件架构图

3.2 概念类图 — 核心抽象与关系

展示 mitmproxy 中关键概念实体及其关系。

mitmproxy 概念类图
图 6:mitmproxy 核心概念类图

3.3 部署图 — 典型部署拓扑

展示 mitmproxy 在不同场景下的部署节点拓扑关系。

mitmproxy 部署拓扑图
图 7:mitmproxy 典型部署拓扑图

4. 配置示例与 Demo

4.1 安装

# macOS
brew install mitmproxy

# pip
pip install mitmproxy

# pipx(推荐隔离安装)
pipx install mitmproxy

# Docker
docker run --rm -it -p 8080:8080 mitmproxy/mitmproxy

# 验证安装
mitmproxy --version

4.2 显式代理模式

最基础的使用方式:客户端配置 HTTP 代理后,mitmproxy 直接拦截 HTTPS。

# 启动(默认监听 localhost:8080)
mitmweb

# 客户端配置(以 curl 为例)
curl -x http://localhost:8080 https://example.com

# 指定监听地址与端口
mitmproxy --listen-host 0.0.0.0 -p 8888

首次启动后,按流程安装 CA 证书:

# 1. 代理配置好后,浏览器访问
#    http://mitm.it —— 下载对应平台的证书
# 2. 或手动安装:
#    macOS: sudo security add-trusted-cert -d -p ssl -p basic \
#           -k /Library/Keychains/System.keychain ~/.mitmproxy/mitmproxy-ca-cert.pem
#    Linux: cp ~/.mitmproxy/mitmproxy-ca-cert.pem /usr/local/share/ca-certificates/mitmproxy.crt
#           sudo update-ca-certificates

4.3 透明代理模式

无需客户端配置代理,通过网络层重定向所有流量到 mitmproxy。

# macOS 透明代理
sudo sysctl -w net.inet.ip.forwarding=1
# 将端口 80/443 流量重定向到 mitmproxy 的 8080
echo "rdr pass on en0 inet proto tcp from any to any port 80 -> 127.0.0.1 port 8080" | sudo pfctl -evf -
echo "rdr pass on en0 inet proto tcp from any to any port 443 -> 127.0.0.1 port 8080" | sudo pfctl -evf -

# 启动
mitmproxy --mode transparent

# Linux (iptables)
sudo iptables -t nat -A PREROUTING -p tcp --dport 80 -j REDIRECT --to-port 8080
sudo iptables -t nat -A PREROUTING -p tcp --dport 443 -j REDIRECT --to-port 8080

4.4 反向代理模式

mitmproxy 放在服务器前端,拦截进出流量。

# 反代到指定上游
mitmdump --mode reverse:https://api.example.com

# HTTP 上游
mitmproxy --mode reverse:http://localhost:3000

# 自定义端口
mitmdump --mode reverse:https://example.com@8443

# TCP/TLS 原始代理
mitmdump --mode reverse:tls://example.com:443
mitmdump --mode reverse:dns://8.8.8.8

4.5 Addon 脚本示例

示例 1:给所有响应添加自定义 Header

# add_header.py
def response(flow):
    flow.response.headers["X-Proxy"] = "mitmproxy"

# 使用:mitmproxy -s add_header.py

示例 2:将指定域名的请求重定向到本地

# redirect.py
from mitmproxy import http

def request(flow: http.HTTPFlow) -> None:
    if flow.request.pretty_host == "api.example.com":
        flow.request.host = "localhost"
        flow.request.port = 3000

示例 3:计数器 Addon(完整类结构)

import logging

class Counter:
    def __init__(self):
        self.num = 0

    def request(self, flow):
        self.num += 1
        logging.info(f"We've seen {self.num} flows")

addons = [Counter()]

示例 4:拦截并发起异步 HTTP 调用

from mitmproxy import ctx, http
import aiohttp

async def request(flow: http.HTTPFlow) -> None:
    async with aiohttp.ClientSession() as session:
        async with session.get("https://check.example.com/api") as resp:
            result = await resp.json()
            ctx.log.info(f"Check result: {result}")

Addon 脚本热加载:修改并保存 -s script.py 文件后,mitmproxy 自动重新导入,无需重启。

4.6 过滤表达式示例

# 只看 example.com 域名的流量
mitmproxy -p 8080 "example.com"

# 只看 POST 请求
mitmproxy "~m POST"

# 只看 4xx/5xx 响应
mitmproxy "~c 4" "~c 5"

# 只看响应中包含 JSON 的
mitmproxy "~ts application/json"

# 组合:POST 请求 且 example.com 域名
mitmproxy "~m POST & example.com"

# 排除 CSS/JS/图片 等静态资源
mitmproxy "!(~a)"

# 标记并重放
mitmdump -nr infile -w outfile "~m post"

# 标记特定 flow 便于后续操作
# 在 TUI 中使用 :mark

5. 实战速查手册

5.1 工具对比与启动

工具界面适用场景流量存储
mitmproxy 终端 TUI 手动分析、少量交互 内存
mitmweb Web 浏览器 可视化分析、新手友好 内存
mitmdump 命令行 脚本化、自动化、录制重放 流式/文件
# 基本启动
mitmproxy              # 终端 TUI,默认 8080
mitmweb                # Web 界面
mitmdump               # 命令行模式

# 保存和读取流量
mitmdump -w outfile    # 保存所有流量到 outfile
mitmdump -r infile     # 读取并分析已保存的流量
mitmdump -nr infile -w outfile "~m post"  # 过滤重放

5.2 代理模式速查

模式命令说明
显式代理(默认)mitmproxy客户端需配置 HTTP 代理
透明代理mitmproxy --mode transparent网络层重定向,需 iptables/pf
反向代理mitmdump --mode reverse:https://x.commitm 在服务器前
上游代理mitmdump --mode upstream:http://x:8081链式代理
SOCKS5mitmdump --mode socks5SOCKS5 服务器
WireGuardmitmweb --mode wireguardVPN 模式,适合移动设备
Local Capturemitmproxy --mode local拦截本机应用(eBPF)
TUNsudo mitmdump --mode tun虚拟网卡模式
DNSmitmdump --mode dnsDNS 服务器 (端口 53)

5.3 过滤表达式速查

表达式含义
~u regex按 URL 过滤
~d regex按域名过滤
~m regex按 HTTP 方法过滤
~c int按响应状态码过滤
~b regex按请求/响应 Body 过滤
~bq regex按请求 Body 过滤
~bs regex按响应 Body 过滤
~h regex按 Header(name: value) 过滤
~hq regex按请求 Header 过滤
~hs regex按响应 Header 过滤
~t regex按 Content-Type 过滤
~a匹配静态资源(CSS/JS/images/fonts)
~q仅有请求(无响应)
~s有响应的请求
~http / ~tcp / ~dns / ~websocket / ~udp按协议过滤
~marked已标记的 flow
~e匹配错误
!取反
&与
|或

5.4 关键 Addon 事件

事件触发时机签名
request客户端请求到达def request(flow: HTTPFlow)
requestheaders请求头(无 body 时)已接收def requestheaders(flow: HTTPFlow)
response服务器响应到达def response(flow: HTTPFlow)
responseheaders响应头(无 body 时)已接收def responseheaders(flow: HTTPFlow)
error发生错误def error(flow: HTTPFlow)
websocket_messageWebSocket 消息到达def websocket_message(flow: HTTPFlow)
tcp_messageTCP 消息到达def tcp_message(flow: TCPFlow)
runningmitmproxy 启动完成def running()
donemitmproxy 即将关闭def done()
configure配置更新时def configure(updated)

5.5 证书管理

文件路径用途
CA 私钥 + 证书~/.mitmproxy/mitmproxy-ca.pemCA 完整密钥对
CA 证书~/.mitmproxy/mitmproxy-ca-cert.pem分发到非 Windows 设备
PKCS12 证书~/.mitmproxy/mitmproxy-ca-cert.p12Windows 使用
CER 证书~/.mitmproxy/mitmproxy-ca-cert.cerAndroid 使用
# 首次运行时自动生成 CA
# 查看 CA 信息
openssl x509 -noout -text -in ~/.mitmproxy/mitmproxy-ca.pem

# 使用自定义 CA
mitmproxy --set confdir=/path/to/my-ca-dir

# 使用自定义服务器证书
mitmproxy --certs *.example.com=cert.pem

5.6 常用选项

-p, --listen-port PORT      # 监听端口(默认 8080)
    --listen-host HOST      # 监听地址(默认 localhost)
-s, --scripts SCRIPT        # 加载 Python Addon 脚本
    --mode MODE             # 代理模式
-r, --read-flows FILE       # 读取已保存的 flows
-w, --save-stream-file FILE # 保存 flows 到文件
    --set option=value      # 设置选项
    --ignore-hosts HOSTS    # 忽略的域名(不拦截)
    --tcp-hosts HOSTS       # 以 TCP 模式代理的域名
    --certs DOMAIN=FILE     # 使用自定义证书
证书安装快捷方法:配置代理后,浏览器访问 http://mitm.it, 按平台指引下载并安装 CA 证书。Android/iOS 安装后还需启用信任(设置→关于→证书信任设置)。